<template>
  <view class="mescroll-uni" :style="[getStyle]">
    <mescroll-uni
      ref="mescrollRef"
      :down="downOption"
      :up="upOption"
      :bottombar="bottomBar"
      :height="height"
      :fixed="fixedValue"
      :top="innerTop"
      :bottom="bottom"
      @init="mescrollInit"
      @up="upCallback"
      @down="downCallback"
      @scroll="scroll"
    >
      <slot />
    </mescroll-uni>
    <view v-if="isEmpty" class="mescroll-uni__empty" :style="[getEmptyStyle]">
      <slot v-if="$slots.empty" name="empty" />
      <m-empty
        v-else
        :tip="option.tip"
        :show-btn="option.showBtn"
        :type="option.type"
        :background="option.background"
        :margin-top="option.marginTop"
        :center="option.center"
        :button-txt="option.buttonTxt"
        @click="handleClick"
      >
      </m-empty>
    </view>
  </view>
</template>

<script lang="ts">
import {
  defineComponent,
  ref,
  PropType,
  onMounted,
  reactive,
  toRefs,
  computed,
  watch,
  nextTick,
} from '@vue/composition-api'
import MescrollUni from '@/mescroll-uni/mescroll-uni.vue'
import boundingClientRect from '@/utils/bounding-client-rect'
import getCurrentComponent from '@/utils/get-current-component'
import addColor from '@/utils/add-color'
export interface IDownOption {
  isLock: boolean //下拉刷新参数配置
  auto?: boolean
}
export interface IUpOption {
  isLock: boolean //上拉加载参数配置
  auto?: boolean
  empty?: IEmptyOption
  onScroll?: boolean
}

export interface IEmptyOption {
  icon?: string
  tip: string
  background?: string
}

export default defineComponent({
  components: {
    MescrollUni,
  },
  props: {
    down: {
      type: Object as PropType<IDownOption>,
      default() {
        return { isLock: false, auto: true }
      },
    },
    up: {
      type: Object as PropType<IUpOption>,
      default() {
        return { isLock: false, auto: true }
      },
    },
    height: {
      type: [String, Number],
      default: '',
    },
    fixed: {
      type: Boolean,
      default: true,
    },
    bottomBar: {
      type: Boolean,
      default: true,
    },
    bottom: {
      type: [String, Number],
      default: 0,
    },
    top: {
      type: Number,
      default: 0,
    },
    useTop: {
      // 解决在轮播图中的定位 算fixed不正确的问题 以订单列表为例子
      type: Boolean,
      default: false,
    },
    historyCollapse: {
      // 解决在查找订单的时候历史搜索原因展开时重新计算scrollTop
      type: [Boolean, Number],
      default: false,
    },
    isEmpty: {
      type: Boolean,
      default: false,
    },
    emptyOption: {
      type: Object,
      default: () => ({}),
    },
    background: {
      type: String,
      default: '#fff',
    },
  },
  // vue3 不能emits和props一直
  // emits: ['up', 'down', 'init'],
  setup(props, { emit, root }) {
    const downOption = ref(props.down)
    const upOption = ref(props.up)
    const state = reactive({
      option: {
        ...{
          tip: '查询数据为空',
          showBtn: false,
          type: 'search',
          center: false,
          buttonTxt: '去逛逛',
        },
        ...props.emptyOption,
      },
      heightVal: props.height,
    })
    upOption.value = {
      ...{
        textNoMore: root.$t('没有更多了'),
      },
      toTop: {
        right: 25,
        bottom: 200,
      },
      ...upOption.value,
    }
    const fixedValue = ref(props.fixed)
    const upCallback = (page: any) => {
      emit('up', page)
    }
    const downCallback = (page: any) => {
      emit('down', page)
    }

    let mescrollObj: any = null
    const mescrollInit = (mescroll: any) => {
      mescrollObj = mescroll
      emit('init', mescroll)
    }
    const scroll = (mescroll: any) => {
      emit('scroll', mescroll)
    }
    const getStyle = computed(() => {
      return {
        height: props.fixed ? state.heightVal + 'px' : props.height,
        backgroundColor: addColor(props.background),
      }
    })
    const getEmptyStyle = computed(() => {
      return {
        backgroundColor: addColor(props.emptyOption.background),
      }
    })
    const handleClick = () => {
      emit('click')
    }
    const vm = getCurrentComponent()
    let innerTop: any = ref()
    watch(
      () => props.emptyOption,
      (val) => {
        nextTick(() => {
          state.option = {
            ...{
              tip: '查询数据为空',
              showBtn: false,
              type: 'search',
              center: false,
            },
            ...val,
          }
        })
      },
      {
        immediate: true,
        deep: true,
      }
    )
    watch(
      () => props.isEmpty,
      (val) => {
        upOption.value = {
          ...upOption.value,
          isLock: val,
        }
      }
    )
    watch(
      () => props.historyCollapse,
      () => {
        watchDomHeiht()
      }
    )
    onMounted(async () => {
      watchDomHeiht()
      uni.$on('historyChange', function (val) {
        watchDomHeiht(val)
      })
    })
    const watchDomHeiht = (val = 0) => {
      nextTick(async () => {
        const mescrollUni = (await boundingClientRect('.mescroll-uni', vm)) as UniApp.NodeInfo
        props.fixed
          ? (innerTop.value = (mescrollUni.top as number) + uni.upx2px(props.top) + uni.upx2px(val) + 'px')
          : ''
        if (props.useTop) {
          innerTop.value = uni.upx2px(props.top) + 'px'
        }
        state.heightVal =
          (mescrollObj.getClientHeight() as number) - (mescrollUni.top as number) - uni.upx2px(props.top)
      })
    }
    return {
      ...toRefs(state),
      upCallback,
      mescrollInit,
      downCallback,
      downOption,
      upOption,
      fixedValue,
      innerTop,
      getStyle,
      getEmptyStyle,
      scroll,
      handleClick,
    }
  },
})
</script>

<style lang="scss" scoped>
.iconfont {
  font-size: var(--font-size);
}
.mescroll-uni {
  position: relative;
  &__empty {
    position: absolute;
    top: 0rpx;
    width: 100%;
    height: 100%;
    z-index: 10;
    border-radius: 16rpx 16rpx 0rpx 0rpx;
  }
}
</style>
